package cn.tedu._07springaop.aop;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect//标志为切面类
@Component//标志为组件,创建对象
public class LogAspect {
//    @Pointcut("execution(public int cn.tedu._07springaop.aop.CalculatorImpl." +
//            "add(..)) ||execution(public int cn.tedu._07springaop.aop.CalculatorImpl." +
//            "sub(..))")


    //@Pointcut("bean(calculatorImpl)")//匹配CalculatorImpl对象中的所有方法,只能拦截所有方法
    @Pointcut("within(cn.tedu._07springaop.aop.CalculatorImpl)")//匹配CalculatorImpl对象中的所有方法
    public void pointcut(){}
//    @Before(value = "pointcut()")//*(..)
//    public void beforeMethod(JoinPoint joinPoint) {
//        String name = joinPoint.getSignature().getName();
//        String args = Arrays.toString(joinPoint.getArgs());
//        System.out.println("[前置通知]"+name+"方法开始，参数为："+ args);
//    }
//    @After(value = "pointcut()")//after拿不到返回值
//    public void afterMethod(JoinPoint joinPoint) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println("[后置通知]"+name+"方法结束");
//    }
//
//    @AfterReturning(value = "pointcut()",returning = "result")//方法顺利执行返回
//    public void afterReturning(JoinPoint joinPoint,Object result) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println("[返回通知]"+name+"方法正常返回，结果为："+result);
//    }
//    @AfterThrowing(value = "pointcut()",throwing = "ex")
//    public void afterThrowing(JoinPoint joinPoint,Throwable ex) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println("[异常通知]"+name+"方法异常，异常信息为："+ex.getMessage());
//    }
    @Around(value = "pointcut()")//环绕通知,等价于前面四种通知
    public Object aroundMethod(ProceedingJoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("[环绕通知]"+name+"方法开始");
        Object result = null;
        try {
            System.out.println("环绕通知-前置通知");
            result = joinPoint.proceed();
            System.out.println("环绕通知-返回通知");
        } catch (Throwable throwable) {
            System.out.println("环绕通知-异常通知");
            throwable.printStackTrace();
        } finally {
            System.out.println("环绕通知-后置通知");
        }
        System.out.println("[环绕通知]"+name+"方法结束，结果为："+result);
        return result;
    }
}
